在經過前面幾天的章節之後,我們對於如何使用JavaScript與相關的知識有一些概念了。
今天我們要來更深入了解JavaScript的運作原理Prototype(原型)與prototype chain(原型鏈)
JavaScript有別於其他程式語言 如:Java、C#等等,本身並沒有類別的概念。
在JavaScript中我們會利用建構函數去建立設計模型
function User(name, age, sex) {
this.name = name,
this.age = age,
this.sex = sex,
this.sayHi = function() {
console.log(this.name + 'Hi');
}
}
並且我們會使用new 這個關鍵字,建立我們的實體。
const Ian = new User('Ian', 22, 'male')
打印出來看看
console.log(Ian);
可以看到被建立為一個實體物件了!!!
測試一下,是否正常
Ian.sayHi()
Jessica.sayHi()
由建構函數new 出一個實體代表我們會建立一個專屬的記憶體位置。
但是若有100個實體,那豈不是創立了100個sayHi method造成效能浪費嗎???
先來測試是否指向不同的位置
console.log(Ian.sayHi === Jessica.sayHi) //false
Ok,結果是沒錯的
那我們要怎麼改進呢???
先把Ian的實體打印出來看看
console.log(Ian)
可以看到Ian其實是去取用User的prototype
那我們換個想法,把User的參考prototype增加一個不就可以共用了嗎!?
User.prototype.sayHi = function() {
console.log(this.name + ' Hi');
}
更改過後的程式碼
function User(name, age, sex) {
this.name = name,
this.age = age,
this.sex = sex
}
User.prototype.sayHi = function() {
console.log(this.name + ' Hi');
}
const Ian = new User('Ian', 22, 'male')
const Jessica = new User('Jessica', 22, 'female')
Ian.sayHi() //Ian Hi
果然跟我們所想的一樣,可以這樣擴充我們的屬性。
打印看看Ian跟Jessica的sayHi function是否相同記憶體
console.log(Ian.sayHi === Jessica.sayHi); //true
太棒了我們成功了解prototype了!!!
那你說JavaScript是怎麼幫我們指向過去到所參考的ProtoType???
答案就是__proto__
把Ian.__proto__打印出來看看是否是利用__proto__連結的
console.log(Ian.__proto__);
沒錯拉!!! Ian.__proto__確實指向到了User的ProtoType
最後我們用Array來做最後測試
建立一個Array實體
const arrayTest = new Array(1,2,3)
console.log(arrayTest.filter((item) => item > 1))
我們有辦法不宣告任何方法即可使用filter等等method,即是透過prototype。